#pragma once

/*--------------------------------------------------------------------------*/

struct BasicVertex
{
	glm::vec3		position;
	glm::vec3		normal;
	glm::vec2		texcoord;
	Color			color;
};

struct GLVertexArray;
struct GLVertexBuffer;
struct GLProgram;

#define ROPENGL_PRIMITIVECONTAINER_SIZE 8

class CommonWrapper
{
protected:
	CommonWrapper();
	~CommonWrapper();

	static glm::ivec4		_colorMask;
	static glm::vec4		_viewport;

public:
	static GLenum			GetError();
	static GLenum			StrToEnum(const std::string& c);

	static void				ColorMask(GLboolean val);
	static void				ColorMask(const glm::ivec4& mask);
	static void				Viewport(float x, float y, float width, float height);
	static void				Viewport(const glm::vec4& viewport);
	static void				DrawFullscreenQuad();
	static void				FreeCommonWrapper();

	/*--------------------------------------------------------------------------*/
	static BasicVertex*		MapPrimitiveContainer(uint vertexCount);
	static void				UnmapPrimitiveContainer();

	static void				DrawPrimitive(GLenum topology, uint vertices);

	/*--------------------------------------------------------------------------*/

	static GLVertexArray*	GetQuadVao();
	static GLVertexArray*	GetCubeVao();
	static GLVertexArray*	GetLargeSphereVao();
	static GLVertexArray*	GetSmallSphereVao();

protected:
	static GLVertexArray*	_largeSphereVao;
	static GLVertexArray*	_smallSphereVao;
	static GLVertexArray*	_cubeVao;
	static GLVertexArray*	_quadVao;

	static void InitializeCubeVao();
	static void InitializeSmallSphere();
	static void InitializeLargeSphere();
	static void InitializeQuadVao();

	/*--------------------------------------------------------------------------*/

	static GLVertexArray* _fullscreenQuadVao;
	static void InitializeFullscreenQuadVao();

	static GLVertexBuffer* _primitiveContainer;

	static GLVertexArray* _primitiveContainerVao;
	static void InitializePrimitiveContainerVao();
};

struct GLUniformBuffer;
struct GLShader;
struct GLProgram;
struct GLFramebuffer;

std::ostream& operator << (std::ostream& buffer, GLUniformBuffer& ubo);
std::ostream& operator << (std::ostream& buffer, GLShader& sh);
std::ostream& operator << (std::ostream& buffer, GLProgram& pr);
std::ostream& operator << (std::ostream& buffer, GLFramebuffer& fbo);